import React, { useRef, useState, useEffect } from "react";
import { Canvas } from "@react-three/fiber";
import * as THREE from "three";
import { useLoader, useFrame } from "@react-three/fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { AnimationMixer, AnimationClip, AmbientLight } from "three";
import { OrbitControls } from "@react-three/drei";

// 为 AnimatedModel 组件的 props 添加类型
interface AnimatedModelProps {
  modelPath: string;
}

const AnimatedModel: React.FC<AnimatedModelProps> = ({ modelPath }) => {
  // GLTFLoader：用于加载GLTF格式的3D模型，这是一种常用的3D模型格式，支持动画和材质。
  const gltf = useLoader(GLTFLoader, modelPath);

  // 使用 useRef 存储 AnimationMixer  AnimationMixer：用于处理动画，它能够播放、暂停、停止动画，并且可以控制动画的时间。
  const mixer = useRef<AnimationMixer>(new AnimationMixer(gltf.scene));

  // 使用 useState 存储动画数据
  const [animations] = useState<AnimationClip[]>(gltf.animations);

  // 灯光 环境光
  const light = new AmbientLight(0x000000, 1);
  gltf.scene.add(light);
  // 使用 useEffect 设置动画播放
  useEffect(() => {
    if (animations && animations.length > 0) {
      animations.forEach((clip) => mixer.current.clipAction(clip).play());
    }
  }, [animations]);

  // 在每一帧更新动画 useFrame：在每一帧调用，用于更新动画，保持动画的流畅性。
  useFrame((state, delta) => mixer.current.update(delta));
  // 大小 定位
  return <primitive object={gltf.scene} position={[0.1, -1, 0]} scale={2} />;
};

const App: React.FC = () => {
  return (
    <Canvas>
      {/* 灯光 */}
      <ambientLight />
      {/* 平行光   是沿着特定方向发射的光。这种光的表现像是无限远，从它发出的光线都是平行的。常常用平行光来模拟太阳光的效果。 太阳足够远，因此我们可以认为太阳的位置是无限远，所以我们认为从太阳发出的光线也都是平行的。 */}
      <directionalLight position={[10, 10, 10]} />
      {/* AnimatedModel   AnimatedModel 是一个用于处理动画模型的类或接口 */}
      <AnimatedModel modelPath="/glb/dt.glb" />
      {/* 轨道控制器（OrbitControls） */}
      <OrbitControls />
    </Canvas>
  );
};

export default App;
